package org.wxd.bi.controller;

import com.alibaba.fastjson.JSONObject;
import org.slf4j.LoggerFactory;
import org.wxd.aop.Aop;
import org.wxd.batis.EntityField;
import org.wxd.batis.query.QueryWhere;
import org.wxd.batis.query.WhereEnum;
import org.wxd.batis.sql.SqlQueryBuilder;
import org.wxd.batis.sql.mysql.MysqlDataHelper;
import org.wxd.batis.sql.mysql.MysqlDataWrapper;
import org.wxd.bi.data.AppFactory;
import org.wxd.str.Base64Util;
import org.wxd.str.StringUtil;

import java.util.*;

/**
 * @author: Troy.Chen(無心道, 15388152619)
 * @version: 2021-10-21 18:04
 **/
public interface BaseQuery {

    default SqlQueryBuilder builderWhere(String queryWhereString) throws Exception {
        SqlQueryBuilder builder = new SqlQueryBuilder(MysqlDataWrapper.Default);
        if (StringUtil.notNullOrEmpty(queryWhereString)) {
            queryWhereString = Base64Util.decode(queryWhereString);
            if (!"{}".equals(queryWhereString)) {

                LoggerFactory.getLogger(BaseQuery.class).debug(queryWhereString);
                JSONObject jsonObject = JSONObject.parseObject(queryWhereString);

                QueryWhere queryWhere = builder.newQueryWhere();
                for (Map.Entry<String, Object> entry : jsonObject.entrySet()) {
                    String key = entry.getKey();
                    JSONObject entryValue = (JSONObject) entry.getValue();
                    for (Map.Entry<String, Object> objectEntry : entryValue.entrySet()) {
                        switch (objectEntry.getKey()) {
                            case "$like": {
                                queryWhere.append(key, WhereEnum.like, objectEntry.getValue());
                            }
                            break;
                            case "$lte": {
                                queryWhere.append(key, WhereEnum.Lte, objectEntry.getValue());
                            }
                            break;
                            case "$gte": {
                                queryWhere.append(key, WhereEnum.Gte, objectEntry.getValue());
                            }
                            break;
                            case "$in": {
                                queryWhere.append(key, WhereEnum.In, objectEntry.getValue().toString());
                            }
                            break;
                            case "$nin": {
                                queryWhere.append(key, WhereEnum.NIn, objectEntry.getValue().toString());
                            }
                            break;
//                    case "$or": {
//                        List<Document> list = new ArrayList();
//                        Document entryDocument = (Document) entryValue;
//                        for (Map.Entry<String, Object> stringObjectEntry : entryDocument.entrySet()) {
//                            EntityField mapping = pushMapping.mapping().getColumnMap().get(stringObjectEntry.getKey());
//                            list.add(new Document(stringObjectEntry.getKey(), convert(mapping, stringObjectEntry.getValue())));
//                        }
//                        entryValue = list;
//                    }
//                    break;
//                    case "$group": {
////                       Aggregates.group();
//                        BasicDBList list = new BasicDBList();
//                        BasicDBObject group = new BasicDBObject();
//                        group.put("_id", entryValue);
//                        group.put("doc", new Document("$first", "$$ROOT"));
//                        list.add(group);
//                        list.add(new Document("$replaceRoot", new Document("newRoot", "$doc")));
//                        return null;
//                    }
                            default: {
                                queryWhere.append(key, WhereEnum.None, objectEntry.getValue());
                            }
                        }
                    }
                }
                if (!queryWhere.getWhereList().isEmpty()) {
                    builder.where(null, queryWhere);
                }
            }
        }
        return builder;
    }

    default Object convert(EntityField mapping, Object source) {
//        if (source instanceof Bson) {
//            return source;
//        }
//        if (source instanceof BSONObject) {
//            return source;
//        }
        try {
            final MysqlDataHelper mysqlDataHelper = Aop.getBean(AppFactory.class).getDataFactory().dataHelper();
            if (source instanceof List) {
                List tmp = (List) source;
                final ArrayList<Object> objects = new ArrayList<>(tmp.size());
                int size = tmp.size();
                for (int i = 0; i < size; i++) {
                    Object o = tmp.get(i);
                    final Object toDbValue = mysqlDataHelper.getDataWrapper().toDbValue(mapping, o);
                    objects.add(toDbValue);
                }
                return objects;
            } else {
                return mysqlDataHelper.getDataWrapper().toDbValue(mapping, source);
            }
        } catch (Exception e) {
        }
        return source;
    }


}
